package com.dao;

import java.io.Serializable;
import java.sql.Connection;
import java.sql.Timestamp;
import java.util.List;
import java.util.Set;

import javax.ejb.TransactionManagementType;

import org.apache.log4j.Logger;
import org.hibernate.CallbackException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.classic.Lifecycle;
import org.hibernate.criterion.Example;
import org.hibernate.engine.spi.SessionImplementor;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.base.BaseDao;
import com.base.PageBean;
import com.bean.ParkManager;
import com.bean.Parkinfo;
import com.bean.ParkinfoManagerRelevance;
import com.bean.RoleInfo;
import com.bean.Userinfo;
import com.util.EncoderHandler;
import com.util.GUtil;

/**
 	* A data access object (DAO) providing persistence and search support for ParkManager entities.
 			* Transaction control of the save(), update() and delete() operations 
		can directly support Spring container-managed transactions or they can be augmented	to handle user-managed Spring transactions. 
		Each of these methods provides additional information for how to configure it for the desired type of transaction control. 	
	 * @see com.bean.ParkManager
  * @author MyEclipse Persistence Tools 
 */
public class ParkManagerDao extends BaseDao  {
	private static final Logger log = Logger.getLogger(ParkManagerDao.class);
		//property constants
	public static final String USER_NAME = "userName";
	public static final String USER_PASSWD = "userPasswd";
	public static final String REAL_NAME = "realName";
	public static final String INTRODUCTION = "introduction";
	public static final String ACCOUNT_BALANCE = "accountBalance";
	public static final String BANK_ACCOUNT = "bankAccount";
	public static final String ROLE = "role";
	public static final String PHONE = "phone";
	public static final String ID_CARD = "idCard";
	public static final String LOGIN_SEQUENCE = "loginSequence";
	public static final String USER_TOKEN = "userToken";
	public static final String CLIENT_ID = "clientId";
	public static final String SUPERIOR_OFFICER = "superiorOfficer";
	public static final String DUTY = "duty";
	public static final String STATUS = "status";

	@SuppressWarnings("unused")
	public ParkManager login(ParkManager pk, String ip, String token, Long userId) throws Exception{
	
		session =  getSession();
		ParkManager parkManager = null;
		String hql = "";
		Query query = null;
		
		if(pk!=null){
			//通过用户名和密码登录
			if(pk==null || pk.getUserName()==null || pk.getUserPasswd()==null )
				return null;
			
			hql = " from ParkManager where "+USER_NAME+"=?  and "+USER_PASSWD+"=?";
			query = session.createQuery(hql);
			String password = EncoderHandler.EncoderPasswordBase64Md5(pk.getUserPasswd());
			query.setString(0, pk.getUserName());
			query.setString(1,  password); //md5
			
		}else if(token!=null && userId!=null){
			
			//通过token登录
			hql = " from ParkManager where userId=?  and userToken=?  and status!=-1";
			query = session.createQuery(hql);
			query.setLong(0, userId);
			query.setString(1, token);
			
		}else{
			throw new Exception(this.getClass()+".login("+pk+","+ip+","+token+","+userId+") 登录出错 ");
		}
		
		parkManager = (ParkManager) query.uniqueResult();
		
		if(parkManager!=null){
			query = session.createQuery("from RoleInfo r where r.roleId= "+parkManager.getRole());
			RoleInfo roleInfo = (RoleInfo)query.uniqueResult();
		 
			if(roleInfo!=null){
//				System.out.println("getRoleName = "+roleInfo.getRoleName());
				parkManager.setRoleName(roleInfo.getRoleName());
			}
			if(parkManager.getStatus()==1){
				Timestamp tm = new Timestamp(System.currentTimeMillis());
				parkManager.setLoginTime(tm);
				query = session.createQuery("update ParkManager set loginTime=? where userId=?");
				query.setTimestamp(0, parkManager.getLoginTime());
				query.setLong(1, parkManager.getUserId());
				query.executeUpdate();
				log.info("update parkManager loginTime="+parkManager.getLoginTime().toLocaleString());
			}
		}
		return parkManager;
	}

	public ParkManager get(Long id){
		return this.findById(id);
	}
	  /*
     * 判断真实姓名是否重复
     */
	public String  findNames(String name){
		log.debug("finding all ParkManager instances");
		session=getSession();
		try {
	         String hql="select userName from ParkManager where userName=?";
	         Query query=session.createQuery(hql);
	         query.setString(0, name);
			 return   (String) query.uniqueResult();
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}
	/**
	 * 根据用户token获取用户信息
	 * <p>Title: getByToken</p>
	 * <p>Description: </p>
	 * @param token  用户token 
	 * @param usercode 用户登录帐号
	 * @return
	 * @throws Exception
	 */
	public ParkManager getByToken(String token, Long userId) throws Exception{
		session = this.getSession();
		String hql = "from ParkManager where userId=? and userToken=? and status!=-1";
		Query query = session.createQuery(hql);
		query.setLong(0, userId);
		query.setString(1, token);
		List<ParkManager> list= query.list();
		if(list==null)
			return null;
		if(list.size()>1){
			String msg = "[fatal]"+ this.getClass()+".getByToken("+token+"), this cannot be appears. User Token shoule be Unique.";
			log.fatal(msg);
			throw new Exception(msg);
		}
		return list.get(0);
	}

	/**
	 * 读取我管辖停车场的用户信息
	 * <p>Title: getMyParkUsers</p>
	 * <p>Description: </p>
	 * @param pm
	 * @return
	 * @throws Exception
	 */
	public List getMyParkUsers(ParkManager parkManager, ParkManager queryCriteriaPM) throws Exception {
		session = getSession();
		
		ParkinfoManagerRelevance pmr = null;
		//查询非删除&角色是收费员或普通管理员的人员
		String hql= "from ParkManager where superiorOfficer=? and role<3 ";
		if(queryCriteriaPM!=null){
			//userName
			if(queryCriteriaPM.getUserName()!=null && !queryCriteriaPM.getUserName().trim().isEmpty())
				hql += " and userName like '%"+queryCriteriaPM.getUserName().trim()+"%' ";
			//realName
			if(queryCriteriaPM.getRealName()!=null && !queryCriteriaPM.getRealName().trim().isEmpty())
				hql += " and realName like '%"+queryCriteriaPM.getRealName().trim()+"%' ";
			//phone
			if(queryCriteriaPM.getPhone()!=null && !queryCriteriaPM.getPhone().trim().isEmpty())
				hql += " and phone like '%"+queryCriteriaPM.getPhone().trim()+"%' ";
		}
		if(queryCriteriaPM!=null && queryCriteriaPM.getStatus()!=null){
			hql += " and status="+queryCriteriaPM.getStatus();
		}else{
			hql += " and status!=-1  ";
		}
		Query query= session.createQuery(hql);
		query.setLong(0, parkManager.getUserId());

		List list = query.list();
		for(Object obj :  list){
			ParkManager pm = (ParkManager)obj;
			hql = "select * from role_info where role_id=?";
			query = session.createSQLQuery(hql).addEntity(RoleInfo.class);
			query.setLong(0, pm.getRole());
			RoleInfo roleInfo = (RoleInfo)query.uniqueResult();
			if(roleInfo!=null){
				pm.setRoleInfo(roleInfo);
				pm.setRoleName(roleInfo.getRoleName());
			}
		}
		log.info("读取我管辖停车场的用户信息 @ getMyParkUsers hql="+hql);
		return list;
	}
	/**
	 * 添加停车场管理用户（管理员&收费员）
	 * <p>Title: add</p>
	 * <p>Description: </p>
	 * @param parkManager
	 * @param parkIds
	 * @return
	 */
	public String add(ParkManager parkManager, Integer[] parkIds) {
		if(parkManager.getRole()>2)
			return GUtil.FAILE;
		log.debug("ParkManager saving ParkManager instance");
		session = getSession();
		try {
			Timestamp tm = new Timestamp(System.currentTimeMillis());
			parkManager.setCreateTime(tm);
			parkManager.setUpdateTime(tm);
			parkManager.setUserPasswd( EncoderHandler.EncoderPasswordBase64Md5(parkManager.getUserPasswd())); // md5
			session.save(parkManager);
			log.debug("ParkManager save successful");
			if(parkIds!=null){
				for(int i=0; i<parkIds.length; i++){
					ParkinfoManagerRelevance pmr = new ParkinfoManagerRelevance(parkIds[i], parkManager.getUserId());
					if(pmr!=null)
						session.save(pmr);
				}
			}
			session.flush();
		} catch (RuntimeException re) {
			log.error("ParkManager save failed", re);
			throw re;
		}
		return GUtil.SUCCESS;
	}
	
	public String delete(Long id,Integer flag) {
		ParkManager pm = this.findById(id);
		if(pm!=null){
			return this.delete(pm, flag);
		}else{
			return GUtil.FAILE;
		}
	}
	public String delete(ParkManager parkManager,Integer flag) {
		log.debug("deleting ParkOrder instance");
		session=getSession();
		try {
			if(flag==null)
				session.delete(parkManager);
			else{
				parkManager.setStatus(flag.shortValue());
				session.update(parkManager);
				session.flush();
			}
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
		return GUtil.SUCCESS;
	}
	public String lock(Long id, Integer flag){
		ParkManager parkManager = this.findById(id);
		if(parkManager!=null){
			return delete1(parkManager, flag);
		}else{
			return GUtil.FAILE;
		}
	}
	public String delete1(ParkManager parkManager,Integer flag) {
		log.debug("deleting ParkOrder instance");
		session = getSession();
		try {
			if(flag==null)
				getSession().delete(parkManager);
			else{
				parkManager.setStatus(flag.shortValue());
				session.update(parkManager);
				session.flush();
			}
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		}
		return GUtil.SUCCESS;
	}
	public String delete(ParkManager persistentInstance) {
		log.debug("deleting ParkManager instance");
		try {
			persistentInstance.setStatus( Short.valueOf((short) -1) );//delete
			getSession().update(persistentInstance);
		//	getSession().delete(persistentInstance);
			log.debug("delete successful");
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			return GUtil.FAILE;
		}
		return GUtil.SUCCESS;
	}

	public ParkManager findById(java.lang.Long id) {
		log.debug("getting ParkManager instance with id: " + id);
		try {
			ParkManager instance = (ParkManager) getSession().get(
					ParkManager.class, id);
			if(instance!=null)
			{
				String hql = "from Parkinfo where PId in (select PId from ParkinfoManagerRelevance where userId=?) ";
				Query query = getSession().createQuery(hql);
				query.setLong(0, instance.getUserId());
				instance.setList( query.list() );
			}
			return instance;
		} catch (RuntimeException re) {
			log.error("get failed", re);
			throw re;
		}
	}
	
	public String update(ParkManager parkManager, Integer[] parkIds) {
		log.debug("attaching update ParkManager instance");
		session = getSession();
	//	Transaction tx = session.beginTransaction();
		try {
			Timestamp tm = new Timestamp(System.currentTimeMillis());
			parkManager.setUpdateTime(tm);
		//	parkManager.setUserPasswd( EncoderHandler.EncoderPasswordBase64Md5(parkManager.getUserPasswd())); // md5
			session.update(parkManager);
			session.flush();
			log.debug("ParkManager update successful");
			String hql = "delete from ParkinfoManagerRelevance where id.userId=?";
			Query query = session.createQuery(hql);
			query.setLong(0, parkManager.getUserId());
			query.executeUpdate();//delete
			if(parkIds!=null){
				for(int i=0; i<parkIds.length; i++){
					ParkinfoManagerRelevance pmr = new ParkinfoManagerRelevance(parkIds[i], parkManager.getUserId());
					session.save(pmr);
				}
			}
			session.flush();
	//		tx.commit();
		} catch (RuntimeException re) {
	//		tx.rollback();
			log.error("ParkManager update failed", re);
			throw re;
		}
		return GUtil.SUCCESS;
	}

	public String update(ParkManager parkManager) {
		log.debug("saving Parkinfo instance");
		session = getSession();
		try {
			session.update(parkManager);
			session.flush();
			log.debug("update successful");
		} catch (RuntimeException re) {
			log.error("update failed", re);
			throw re;
		}
		return GUtil.SUCCESS;
	}
    public void save(ParkManager transientInstance) {
        log.debug("saving ParkManager instance");
        try {
            getSession().save(transientInstance);
            log.debug("save successful");
        } catch (RuntimeException re) {
            log.error("save failed", re);
            throw re;
        }
    }
    
    public String add(ParkManager manager) {
        log.debug("saving Userinfo instance");
        try {
            getSession().save(manager);
            log.debug("save successful");
        } catch (RuntimeException re) {
            log.error("save failed", re);
            throw re;
        }
        return GUtil.SUCCESS;
    }
    
    public List findByExample(ParkManager instance) {
        log.debug("finding ParkManager instance by example");
        try {
            List results = getSession()
                    .createCriteria("com.dao.ParkManager")
                    .add(Example.create(instance))
            .list();
            log.debug("find by example successful, result size: " + results.size());
            return results;
        } catch (RuntimeException re) {
            log.error("find by example failed", re);
            throw re;
        }
    }    
    
    public List findByProperty(String propertyName, Object value) {
      log.debug("finding ParkManager instance with property: " + propertyName
            + ", value: " + value);
      try {
         String queryString = "from ParkManager as model where model." 
         						+ propertyName + "= ?";
         Query queryObject = getSession().createQuery(queryString);
		 queryObject.setParameter(0, value);
		 return queryObject.list();
      } catch (RuntimeException re) {
         log.error("find by property name failed", re);
         throw re;
      }
	}

	public List findByUserName(Object userName
	) {
		return findByProperty(USER_NAME, userName
		);
	}
	
	public List findByUserPasswd(Object userPasswd
	) {
		return findByProperty(USER_PASSWD, userPasswd
		);
	}
	
	public List findByRealName(Object realName
	) {
		return findByProperty(REAL_NAME, realName
		);
	}
	
	public List findByIntroduction(Object introduction
	) {
		return findByProperty(INTRODUCTION, introduction
		);
	}
	
	public List findByAccountBalance(Object accountBalance
	) {
		return findByProperty(ACCOUNT_BALANCE, accountBalance
		);
	}
	
	public List findByBankAccount(Object bankAccount
	) {
		return findByProperty(BANK_ACCOUNT, bankAccount
		);
	}
	
	public List findByRole(Object role
	) {
		return findByProperty(ROLE, role
		);
	}
	
	public List findByPhone(Object phone
	) {
		return findByProperty(PHONE, phone
		);
	}
	
	public List findByIdCard(Object idCard
	) {
		return findByProperty(ID_CARD, idCard
		);
	}
	
	public List findByLoginSequence(Object loginSequence
	) {
		return findByProperty(LOGIN_SEQUENCE, loginSequence
		);
	}
	
	public List findByUserToken(Object userToken
	) {
		return findByProperty(USER_TOKEN, userToken
		);
	}
	
	public List findByClientId(Object clientId
	) {
		return findByProperty(CLIENT_ID, clientId
		);
	}
	
	public List findBySuperiorOfficer(Object superiorOfficer
	) {
		return findByProperty(SUPERIOR_OFFICER, superiorOfficer
		);
	}
	
 
	/**
	 * 储物箱停车场用户
	 * <p>Title: query</p>
	 * <p>Description: </p>
	 * @param parkManager
	 * @param parkId
	 * @return 停车场用户列表 List<ParkManager>
	 */
	public List query(ParkManager parkManager, Long parkId) {
		log.debug("finding all ParkManager instances");
		try {
			//查询所有停车场
			if(parkId==null || parkId<1){
				String hql = "from ParkManager where statu!=-1";
				Query queryObject = getSession().createSQLQuery(hql).addEntity(ParkManager.class);
				if(parkManager!=null){
					if(parkManager.getUserName()!=null)
						;
				}
				return queryObject.list();
			}

			//根据停车场ID查询对应的用户
			String hql = " from ParkManager where userId in ( select  userId from ParkinfoManagerRelevance where  PId=?)";
			Query query = getSession().createQuery(hql);
			query.setLong(0, parkId);
			List<ParkManager> pmlist = query.list();
			return pmlist;

		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}
	

	public List findAll() {
		log.debug("finding all ParkManager instances");
		try {
			String queryString = "from ParkManager";
	         Query queryObject = getSession().createQuery(queryString);
			 return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}
	public List find(ParkManager manager,PageBean page) {
		StringBuffer sb = new StringBuffer();
		session = getSession();
		log.debug("finding all ParkManager instances");
		try {
			sb.append("from ParkManager where role=3 and status!=-1");
			if(manager!=null){
				if(manager.getRealName()!=null){
					sb.append(" and realName like '%"+ manager.getRealName()+ "%'");	
				}
				if(manager.getStatus()!=null){
					Short s=manager.getStatus();
					sb.append(" and status ='"+ s+ "'");	
				}
				if(manager.getPhone()!=null){
					sb.append(" and phone like '"+ manager.getPhone()+"%'");	
				}
				if(manager.getRole()!=null){
					Short ro=manager.getRole();
					sb.append(" and role = '"+ro+ "'");	
				}
			}
			Long count = (Long) session.createQuery("select count(*) "+ sb.toString()).uniqueResult();
			if(page!=null && count!=null )
				page.setTotalRow(count.intValue());
				Query queryObject = session.createQuery(sb.toString());
				if(page!=null && page.getPageSize()>0 && page.getCurrentPage()>0){
					queryObject.setFirstResult( (page.getCurrentPage()-1)*page.getPageSize());
					queryObject.setMaxResults( page.getPageSize() );
				}
			 return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find all failed", re);
			throw re;
		}
	}
	
    public ParkManager merge(ParkManager detachedInstance) {
        log.debug("merging ParkManager instance");
        try {
            ParkManager result = (ParkManager) getSession()
                    .merge(detachedInstance);
            log.debug("merge successful");
            return result;
        } catch (RuntimeException re) {
            log.error("merge failed", re);
            throw re;
        }
    }

    public void attachDirty(ParkManager instance) {
        log.debug("attaching dirty ParkManager instance");
        try {
            getSession().saveOrUpdate(instance);
            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }
    
    public void attachClean(ParkManager instance) {
        log.debug("attaching clean ParkManager instance");
        try {
            getSession().lock(instance, LockMode.NONE);
            log.debug("attach successful");
        } catch (RuntimeException re) {
            log.error("attach failed", re);
            throw re;
        }
    }

}